package com.wlyuan.index.application.service;

import com.alibaba.fastjson.JSONObject;
import com.wlyuan.core.domain.valueobj.OrderId;
import com.wlyuan.index.api.IOrderIndexService;
import com.wlyuan.index.api.dto.order.OrderIndexDTO;
import com.wlyuan.index.api.dto.order.OrderIndexFilterDTO;
import com.wlyuan.index.api.dto.order.OrderReindexAllDTO;
import com.wlyuan.index.api.dto.order.OrderReindexDTO;
import com.wlyuan.index.api.vo.OrderIndexScrollVO;
import com.wlyuan.index.api.vo.OrderIndexSumVO;
import com.wlyuan.index.api.vo.OrderIndexVO;
import com.wlyuan.index.application.translator.OrderIndexTranslator;
import com.wlyuan.index.domain.index.factory.OrderIndexFactory;
import com.wlyuan.index.domain.index.repository.OrderIndexRepository;
import com.wlyuan.index.domain.index.repository.old.OrderIndexOldRepository;
import com.wlyuan.index.domain.index.service.OrderIndexRenewService;
import com.wlyuan.index.domain.index.service.OrderIndexSearchService;
import com.wlyuan.index.domain.index.service.reindex.OrderReindexService;
import com.wlyuan.index.domain.source.factory.SourceFactory;
import com.wlyuan.tools.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import lombok.var;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.dubbo.config.annotation.DubboService;

import java.util.List;
import java.util.Map;

@DubboService
@Slf4j
@RequiredArgsConstructor
public class OrderIndexServiceImpl implements IOrderIndexService {
    private final OrderIndexRepository indexRepository;
    private final OrderIndexOldRepository indexOldRepository;
    private final SourceFactory sourceFactory;
    private final OrderReindexService reindexService;
    private final OrderIndexSearchService searchService;
    private final OrderIndexRenewService renewService;

    @Override
    public void index(Long orderId) {
        renewService.add(new OrderId(orderId));
    }

    @Override
    public void index(List<Long> orderIds) {
        if (CollectionUtils.isEmpty(orderIds)) {
            return;
        }
        orderIds.forEach(this::index);
    }

    @Override
    public void index(OrderIndexDTO order) {
        sourceFactory.create(order);
        renewService.add(new OrderId(order.getOrderId()));
    }

    @Override
    public Page<OrderIndexVO> search(OrderIndexFilterDTO filter) {
        return searchService.search(filter);
    }

    @Override
    public OrderIndexScrollVO scroll(OrderIndexFilterDTO filter) {
        return OrderIndexTranslator.translate(searchService.scroll(filter));
    }

    @Override
    public OrderIndexScrollVO scroll(String scrollId) {
        return OrderIndexTranslator.translate(searchService.scroll(scrollId));
    }

    @Override
    public OrderIndexSumVO searchSum(OrderIndexFilterDTO filter) {
        return searchService.searchSum(filter);
    }

    @Override
    public Map<Long, OrderIndexSumVO> searchSums(OrderIndexFilterDTO filter) {
        return searchService.searchSums(filter);
    }

    @Override
    public void reindex(Long orderId) {
        reindexService.reindex(new OrderId(orderId));
    }

    @Override
    public void reindex(OrderReindexDTO reindex) {
        reindexService.reindex(reindex);
    }

    @Override
    public void reindexAll(OrderReindexAllDTO reindex) {
        reindexService.reindex(reindex);
    }

    @Override
    public void remove(Long orderId) {
        indexRepository.deleteById(orderId);
    }

    @Override
    public OrderIndexVO getIndexById(Long orderId) {
        var index = indexRepository.ofId(new OrderId(orderId));
        return OrderIndexTranslator.translate(index);
    }

    @Override
    public JSONObject insight(Long orderId) {
        var source = sourceFactory.getSourceById(new OrderId(orderId));
        source.put("newIndex", this.getIndexById(orderId));
        source.put("oldIndex", indexOldRepository.ofId(new OrderId(orderId)));
        return source;
    }
}
